﻿using System;
using System.Runtime.InteropServices;
using UnityEngine;

public static class vp_TimeUtility
{
    private static float HoursToDegreesInternal(float hours, float minutes = 0f, float seconds = 0f)
    {
        return (((hours * 30f) + (minutes * 0.5f)) + (seconds * 0.008333333f));
    }

    private static float MilliSecondsToDegreesInternal(float milliSeconds)
    {
        return (milliSeconds * 0.36f);
    }

    private static float MinutesToDegreesInternal(float minutes, float seconds = 0f, float milliSeconds = 0f)
    {
        return (((minutes * 6f) + (seconds * 0.1f)) + (milliSeconds * 0.0001f));
    }

    private static float SecondsToDegreesInternal(float seconds, float milliSeconds = 0f)
    {
        return ((seconds * 6f) + (milliSeconds * 0.006f));
    }

    public static Vector3 SystemTimeToDegrees(bool smooth = true)
    {
        return SystemTimeToDegrees(DateTime.Now, smooth);
    }

    public static Vector3 SystemTimeToDegrees(DateTime time, bool smooth = true)
    {
        return new Vector3(HoursToDegreesInternal((float) time.Hour, !smooth ? 0f : ((float) time.Minute), !smooth ? 0f : ((float) time.Second)), MinutesToDegreesInternal((float) time.Minute, !smooth ? 0f : ((float) time.Second), !smooth ? 0f : ((float) time.Millisecond)), SecondsToDegreesInternal((float) time.Second, !smooth ? 0f : ((float) time.Millisecond)));
    }

    public static float SystemTimeToSeconds()
    {
        return SystemTimeToSeconds(DateTime.Now);
    }

    public static float SystemTimeToSeconds(DateTime systemTime)
    {
        return UnitsToSeconds(SystemTimeToUnits(systemTime));
    }

    public static string SystemTimeToString(bool showHours, bool showMinutes, bool showSeconds, bool showTenths, bool showHundredths, bool showMilliSeconds, char delimiter = ':')
    {
        return SystemTimeToString(DateTime.Now, showHours, showMinutes, showSeconds, showTenths, showHundredths, showMilliSeconds, delimiter);
    }

    public static string SystemTimeToString(DateTime systemTime, bool showHours, bool showMinutes, bool showSeconds, bool showTenths, bool showHundredths, bool showMilliSeconds, char delimiter = ':')
    {
        return TimeToString(SystemTimeToSeconds(systemTime), showHours, showMinutes, showSeconds, showTenths, showHundredths, showMilliSeconds, delimiter);
    }

    public static Units SystemTimeToUnits()
    {
        return SystemTimeToUnits(DateTime.Now);
    }

    public static Units SystemTimeToUnits(DateTime systemTime)
    {
        return new Units { hours = systemTime.Hour, minutes = systemTime.Minute, seconds = systemTime.Second, deciSeconds = (int) (((float) systemTime.Millisecond) / 100f), centiSeconds = systemTime.Millisecond / 10, milliSeconds = systemTime.Millisecond };
    }

    public static float TimeToDegrees(float seconds, bool includeHours = false, bool includeMinutes = false, bool includeSeconds = true, bool includeMilliSeconds = true)
    {
        Units units = TimeToUnits(seconds);
        if ((includeHours && includeMinutes) && includeSeconds)
        {
            return HoursToDegreesInternal((float) units.hours, (float) units.minutes, (float) units.seconds);
        }
        if (includeHours && includeMinutes)
        {
            return HoursToDegreesInternal((float) units.hours, (float) units.minutes, 0f);
        }
        if ((includeMinutes && includeSeconds) && includeMilliSeconds)
        {
            return MinutesToDegreesInternal((float) units.minutes, (float) units.seconds, (float) units.milliSeconds);
        }
        if (includeMinutes && includeSeconds)
        {
            return MinutesToDegreesInternal((float) units.minutes, (float) units.seconds, 0f);
        }
        if (includeSeconds && includeMilliSeconds)
        {
            return SecondsToDegreesInternal((float) units.seconds, (float) units.milliSeconds);
        }
        if (includeHours)
        {
            return HoursToDegreesInternal((float) units.hours, 0f, 0f);
        }
        if (includeMinutes)
        {
            return MinutesToDegreesInternal((float) units.minutes, 0f, 0f);
        }
        if (includeSeconds)
        {
            return TimeToDegrees((float) units.seconds, false, false, true, true);
        }
        if (includeMilliSeconds)
        {
            return MilliSecondsToDegreesInternal((float) units.milliSeconds);
        }
        Debug.LogError("Error: (vp_TimeUtility.TimeToDegrees) This combination of time units is not supported.");
        return 0f;
    }

    public static string TimeToString(float timeInSeconds, bool showHours, bool showMinutes, bool showSeconds, bool showTenths, bool showHundredths, bool showMilliSeconds, char delimiter = ':')
    {
        Units units = TimeToUnits(timeInSeconds);
        string str = (units.hours >= 10) ? units.hours.ToString() : ("0" + units.hours.ToString());
        string str2 = (units.minutes >= 10) ? units.minutes.ToString() : ("0" + units.minutes.ToString());
        string str3 = (units.seconds >= 10) ? units.seconds.ToString() : ("0" + units.seconds.ToString());
        string str4 = units.deciSeconds.ToString();
        string str5 = (units.centiSeconds >= 10) ? units.centiSeconds.ToString() : ("0" + units.centiSeconds.ToString());
        string str6 = (units.milliSeconds >= 100) ? units.milliSeconds.ToString() : ("0" + units.milliSeconds.ToString());
        str6 = (units.milliSeconds >= 10) ? str6 : ("0" + str6);
        string[] textArray1 = new string[] { !showHours ? string.Empty : str, !showMinutes ? string.Empty : (delimiter + str2), !showSeconds ? string.Empty : (delimiter + str3), !showTenths ? string.Empty : (delimiter + str4), !showHundredths ? string.Empty : (delimiter + str5), !showMilliSeconds ? string.Empty : (delimiter + str6) };
        char[] trimChars = new char[] { delimiter };
        return string.Concat(textArray1).TrimStart(trimChars);
    }

    public static Units TimeToUnits(float timeInSeconds)
    {
        Units units;
        return new Units { hours = ((int) timeInSeconds) / 0xe10, minutes = (((int) timeInSeconds) - (units.hours * 0xe10)) / 60, seconds = ((int) timeInSeconds) % 60, deciSeconds = ((int) ((timeInSeconds - units.seconds) * 10f)) % 60, centiSeconds = (int) (((timeInSeconds - units.seconds) * 100f) % 600f), milliSeconds = (int) (((timeInSeconds - units.seconds) * 1000f) % 6000f) };
    }

    public static float UnitsToSeconds(Units units)
    {
        float num = 0f;
        num += units.hours * 0xe10;
        num += units.minutes * 60;
        num += units.seconds;
        num += units.deciSeconds * 0.1f;
        num += units.centiSeconds / 100;
        return (num + (units.milliSeconds / 0x3e8));
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct Units
    {
        public int hours;
        public int minutes;
        public int seconds;
        public int deciSeconds;
        public int centiSeconds;
        public int milliSeconds;
    }
}

